package controller

import (
	"context"
	"example/web-service-gin/db/es"
	"example/web-service-gin/db/mgdb"
	_ "example/web-service-gin/docs"
	"fmt"
	. "fmt"
	"github.com/gin-gonic/gin"
	"go.mongodb.org/mongo-driver/mongo"
	"gopkg.in/mgo.v2/bson"
	"net/http"
	"strconv"
	"time"
)

var (
	c  = mgdb.GetMgoCli()
	db *mongo.Database
)
var ctx context.Context

var client *mongo.Client

//2.选择数据库 my_db里的某个表
var collection *mongo.Collection = c.Database("my_db").Collection("my_collection")

type User struct {
	ID   string "json:id"
	Name string "json:name"
}

// gin-swagger middleware
// swagger embed files
type album struct {
	ID     string `json:"id"`
	Title  string `json:"title"`
	Artist string `json:"artist"`
	Price  string `json:"price"`
}
type user struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

var users = []user{
	{Username: "demo", Password: "000000"},
	{Username: "xiaohuang", Password: "000000"},
}

type Student struct {
	Name         string  `json:"name"`
	Age          int64   `json:"age"`
	AverageScore float64 `json:"average_score"`
}

// 查
// ShowAccount    根据id查询
// @Summary      根据id查询
// @Description  get string by ID
// @Tags         User
// @Accept       json
// @Produce      json
// @Param        title   path      string  true  "Account title"
// @Success      200  {object}  album
// @Router       /show/{title} [get]
func Show(c *gin.Context) {
	// 根据title查询
	var title = c.Param("title")
	Println("++++++++++++++++++++", title)
	// 获得操作数据库的游标
	// cur其实是文档流
	cur, err := collection.Find(ctx, bson.M{"title": title})
	if err != nil {
		Println("ID", err)
	}
	fmt.Println(cur)
	//延迟关闭游标
	defer cur.Close(ctx)
	recipes := make([]album, 0)
	for cur.Next(ctx) {
		var recipe album
		// 将查询到的文档装配为Recipe结构体的实体
		cur.Decode(&recipe)
		recipes = append(recipes, recipe)
	}

	c.JSON(http.StatusOK, recipes)

}

// 增
// ShowAccount 增加
// @Summary      增加一条数据
// @Description  get string by ID
// @Tags         User
// @Accept       json
// @Produce      json
// @Param        body body album true "请求body"
// @Success      200  {object}  album
// @Router       /add [post]
func Add(c *gin.Context) {
	var json album
	// ShouldBind()会根据请求的Content-Type自行选择绑定器
	err := c.ShouldBind(&json)
	if err != nil {
		fmt.Println(err.Error())
	}
	//插入某一条数据
	iResult, err := collection.InsertOne(context.TODO(), json)
	if err != nil {
		fmt.Print(err)
		return
	}
	Println(iResult)
	c.IndentedJSON(http.StatusOK, gin.H{
		"code":   http.StatusOK,
		"albums": iResult,
	})
}

// 删
// ShowAccount 删除
// @Summary      Show an user
// @Description  get string by ID
// @Tags         User
// @Accept       json
// @Produce      json
// @Param        id   path      int  true  "Account ID"
// @Success      200  {object}  album
// @Router       /delete/{id} [delete]
func Delete(c *gin.Context) {
	ID := c.Param("id")
	Println("ID：" + ID)
	res, err := collection.DeleteOne(ctx, bson.M{"id": ID})
	if err != nil {
		Println(err)
	}
	c.IndentedJSON(http.StatusOK, gin.H{
		"code":   http.StatusOK,
		"albums": res,
	})
}

// 改
// ShowAccount    查询
// @Summary      Show an User
// @Description  get string by ID
// @Tags         User
// @Accept       json
// @Produce      json
// @Param        id   path      string  true  "Account ID"
// @Param        body body album true "请求body"
// @Success      200  {object}  album
// @Router       /update/{id} [put]
func Update(c *gin.Context) {
	id := c.Param("id")
	var data album
	err := c.ShouldBind(&data)
	if err != nil {
		Println(err)
	}
	Println(id)
	Println(data.ID)
	res, err := collection.UpdateOne(ctx, bson.M{"_id": id}, bson.D{{Name: "$set", Value: bson.D{
		{
			Name:  "id",
			Value: data.ID,
		},
		{
			Name:  "title",
			Value: data.Title,
		},
		{
			Name:  "artist",
			Value: data.Artist,
		},
		{
			Name:  "Price",
			Value: data.Price,
		},
	}}})
	c.IndentedJSON(http.StatusOK, gin.H{
		"code":   http.StatusOK,
		"albums": res,
	})

}

// 中间件
func M1(c *gin.Context) {
	Println("开始+++++++++++++++++")
	start := time.Now()
	c.Next()
	cost := time.Since(start)
	Println("结束", cost)

}

// es
// 增
// ShowAccount 增加
// @Summary      Show an es
// @Description  get string by ID
// @Tags         ES
// @Accept       json
// @Produce      json
// @Param        body body Student true "请求body"
// @Success      200  {object}  Student
// @Router       /esAdd [post]
func EsAdd(c *gin.Context) {
	var json Student
	err1 := c.ShouldBind(&json)
	if err1 != nil {
		fmt.Println(err1.Error())
	}
	// 获取连接
	var esclient, err = es.GetESClient()

	//使用结构体
	put1, err := esclient.Index().
		Index("user").
		Type("employee").
		BodyJson(json).
		Do(context.Background())
	if err != nil {
		panic(err)
	}
	fmt.Printf("Indexed tweet %s to index s%s, type %s\n", put1.Id, put1.Index, put1.Type)
	c.JSON(http.StatusOK, gin.H{
		"data": put1,
	})
}

// 查所有分页
// ShowAccount    查询
// @Summary      Show an es
// @Description  get string by ID
// @Tags         ES
// @Accept       json
// @Produce      json
// @Param        size   query      string  true  "size"
// @Param        page   query      string  true  "page"
// @Success      200  {object}  Student
// @Router       /esShow [get]
func EsSearchAll(c *gin.Context) {
	// 获取连接
	var esclient, err = es.GetESClient()
	size, _ := strconv.Atoi(c.Query("size"))
	page, _ := strconv.Atoi(c.Query("page"))

	Println(size, page)
	//取所有
	res, err := esclient.Search("user").Size(size).From((page - 1) * size).Type("employee").Do(context.Background())
	if err != nil {
		Println(err)
	}
	c.JSON(http.StatusOK, gin.H{
		"data": res,
	})
}

// 根据id查询
// ShowAccount    查询
// @Summary      Show an es
// @Description  get string by ID
// @Tags         ES
// @Accept       json
// @Produce      json
// @Param        id   path      string  true  "Account ID"
// @Success      200  {object}  Student
// @Router       /getById/{id} [get]
func GetById(c *gin.Context) {
	id := c.Param("id")
	fmt.Println(id)
	var esclient, err = es.GetESClient()
	//通过id查找
	get1, err := esclient.Get().Index("user").Type("employee").Id(id).Do(context.Background())
	if err != nil {
		Println(err)
	}
	c.JSON(http.StatusOK, gin.H{
		"data": get1,
	})
}

// 根据id删除
// ShowAccount    查询
// @Summary      Show an es
// @Description  get string by ID
// @Tags         ES
// @Accept       json
// @Produce      json
// @Param        id   path      string  true  "Account ID"
// @Success      200  {object}  Student
// @Router       /esDelete/{id} [delete]
func EsDelete(c *gin.Context) {
	id := c.Param("id")
	fmt.Println(id)
	var esclient, err = es.GetESClient()
	//通过id删除
	delete1, err := esclient.Delete().Index("user").Type("employee").Id(id).Do(context.Background())
	if err != nil {
		Println(err)
	}
	c.JSON(http.StatusOK, gin.H{
		"data": delete1,
	})
}

// 修改
// ShowAccount    查询
// @Summary      Show an es
// @Description  get string by ID
// @Tags         ES
// @Accept       json
// @Produce      json
// @Param        id   path      string  true  "Account ID"
// @Param        body body Student true "请求body"
// @Success      200  {object}  Student
// @Router       /esUpdate/{id} [put]
func EsUpdate(c *gin.Context) {
	id := c.Param("id")
	fmt.Println(id)
	var json Student
	err1 := c.ShouldBind(&json)

	if err1 != nil {
		fmt.Println(err1.Error())
	}

	var esclient, err = es.GetESClient()
	if err != nil {
		Println(err.Error())
	}
	res, err := esclient.Update().
		Index("user").
		Type("employee").
		Id(id).
		Doc(json).
		Do(context.Background())
	c.JSON(http.StatusOK, gin.H{
		"data": res,
	})

}
